using System;
using System.Text;
using System.IO;
using System.Diagnostics;
using System.Xml;
using System.Xml.XPath;
using System.Collections.Generic;

namespace My.IdlConverter.Core.Cfg
{
    public static class Configuration
    {
        private static string _currentTemplate = "default";

        private static XmlDocument m_doc;

        public static string Version
        {
            get { return "1.0.0"; }
        }

        public static string InterfaceFolder
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//InterfaceFolder");
                return node.InnerText;
            }
        }

        public static string ClassFolder
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//ClassFolder");
                return node.InnerText;
            }   
        }

        public static string TypeMappingFile
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//TypeMappingFile");
                return ResolveRelativePath(node.InnerText);
            }
        }

        public static string GuidFile
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//GuidFile");
                return ResolveRelativePath(node.InnerText);
            }
        }

        public static string FilterSettingPath
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//FilterSettingPath");
                return ResolveRelativePath(node.InnerText);
            }
        }

        public static string TemplatePath
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//TemplatePath");
                return ResolveRelativePath(node.InnerText);
            }
        }

        public static string ReturnTypeFormatStrategy
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//ReturnTypeFormatStrategy");
                return node.InnerText;
            }
        }

        public static string ParameterTypeFormatStrategy
        {
            get
            {
                XmlNode node = SelectNode(CurrentTemplate).SelectSingleNode("//ParameterTypeFormatStrategy");
                return node.InnerText;
            }
        }

        public static string CurrentTemplate
        {
            get
            {
                return _currentTemplate;
            }
            set
            {
                if (value.Length == 0)
                    throw new ArgumentException("The current template should not be empty.");
                _currentTemplate = value;
            }
        }

        public static void Load(string cfgXmlFile)
        {
            m_doc = new XmlDocument();
            m_doc.Load(cfgXmlFile);
        }

        public static void Load(string templateName, string cfgXmlFile)
        {
            Load(cfgXmlFile);
            CurrentTemplate = templateName;
        }

        private static XmlNode SelectNode(string templateName)
        {
            string xPath = String.Format("//EnviromentSettings/EnviromentSetting");
            XmlNodeList nodeList = m_doc.SelectNodes(xPath);
            foreach (XmlNode nextNode in nodeList)
            {
                if (nextNode.Attributes["ID"].Value.Equals(templateName))
                    return nextNode;
            }

            return null;
        }

        private static string ResolveRelativePath(string relativePath)
        {
            string codebase = System.Reflection.Assembly.GetExecutingAssembly().CodeBase;
            codebase = codebase.Remove(0,"file:///".Length);
            int index = codebase.LastIndexOf('/');
            string fullPath = Path.Combine(codebase.Substring(0, index), relativePath);

            return fullPath;
        }
    }
}
